﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	public class HideShowElement
	{
		public HideShowElement(Autodesk.Revit.DB.Document doc, UIDocument uiDoc)
		{
			this._uiDoc = uiDoc;
			this._doc = doc;
		}

		public void showSystem()
		{
			this.showElements(new Guid("F47C859B-EA6F-45F0-B082-5F9D6AD72A0F"), "HideSystem");
		}

		public void showLerHide()
		{
			this.showElements(new Guid("41E2793D-FA86-4419-9D94-1C051945EA35"), "SpinkLerHide");
		}

		private void showElements(Guid guid, string name)
		{
			(from s in YJKElementFilter.GetElementByClass(typeof(Autodesk.Revit.DB.View), this._doc)
			where s.Category != null && (s is ViewPlan || s is View3D)
			select s).ToList<Element>();
			this.eles = InnerUtil.getDataInProject(this._doc, guid, name, true);
			if (this.eles != null && this.eles.Count<ElementId>() > 0 && this._doc.ActiveView != null)
			{
				this._doc.ActiveView.UnhideElements(this.eles);
			}
			this.eles.Clear();
		}

		public void spinkLerHide()
		{
			List<Element> list = (from s in YJKElementFilter.GetElementByClass(typeof(Autodesk.Revit.DB.View), this._doc)
			where s.Category != null && s is ViewPlan
			select s).ToList<Element>();
			List<FamilyInstance> sprinklers = YJKElementFilter.GetElementByCategory(this._doc, typeof(FamilyInstance), BuiltInCategory.OST_Sprinklers).Cast<FamilyInstance>().ToList<FamilyInstance>();
			this.findConnectElement(sprinklers);
			if (this.eles != null && this.eles.Count<ElementId>() > 0)
			{
				InnerUtil.StoreDataInProject(this._doc, new Guid("41E2793D-FA86-4419-9D94-1C051945EA35"), "SpinkLerHide", this.eles, false);
				if (this._doc.ActiveView != null)
				{
					list = new List<Element>
					{
						this._doc.ActiveView
					};
				}
				foreach (Element element in list)
				{
					Autodesk.Revit.DB.View view = (Autodesk.Revit.DB.View)element;
					ViewDetailLevel viewDetailLevel = 0;
					if ((int)view.DetailLevel == 3)
					{
						view.DetailLevel = (ViewDetailLevel)2;
						this._doc.Regenerate();
                        viewDetailLevel = (ViewDetailLevel)3;
					}
					view.HideElements(this.eles);
					this._doc.Regenerate();
                    if ((int)viewDetailLevel == 3)
					{
						view.DetailLevel = viewDetailLevel;
						this._doc.Regenerate();
					}
				}
			}
			this.eles.Clear();
		}

		public void hideSystem()
		{
			List<Element> list = (from s in YJKElementFilter.GetElementByClass(typeof(Autodesk.Revit.DB.View), this._doc)
			where s.Category != null && (s is ViewPlan || s is View3D)
			select s).ToList<Element>();
			SearchBranch searchBranch = new SearchBranch(this._uiDoc);
			SystemSelectionFilter selectionFilter = new SystemSelectionFilter();
			searchBranch.PickFirstNearElement(selectionFilter, "请选择系统管道！");
			searchBranch.DoSearch();
			this.setHideElement(searchBranch.GetListRoot().Next);
			if (this.eles != null && this.eles.Count<ElementId>() > 0 && list != null && list.Count<Element>() > 0)
			{
				InnerUtil.StoreDataInProject(this._doc, new Guid("F47C859B-EA6F-45F0-B082-5F9D6AD72A0F"), "HideSystem", this.eles, false);
				if (this._doc.ActiveView != null)
				{
					this.hideSystemEle(new List<Element>
					{
						this._doc.ActiveView
					});
				}
			}
			this.eles.Clear();
		}

		private void findConnectElement(List<FamilyInstance> sprinklers)
		{
			if (sprinklers != null && sprinklers.Count<FamilyInstance>() > 0)
			{
				foreach (FamilyInstance elem in sprinklers)
				{
					List<Connector> elementAllConnector = YJKRevitTools.GetElementAllConnector(elem);
					if (elementAllConnector != null && elementAllConnector.Count<Connector>() == 1)
					{
						Connector connector = elementAllConnector.FirstOrDefault<Connector>();
						if (connector.IsConnected)
						{
							Element elementByAllRefs = this.getElementByAllRefs(connector.AllRefs, typeof(PipingSystem));
							if (elementByAllRefs is Pipe && YJKRevitTools.isRiserPipe((Pipe)elementByAllRefs))
							{
								this.eles.Add(elementByAllRefs.Id);
							}
							else if (elementByAllRefs is FamilyInstance)
							{
								elementByAllRefs = this.getElementByAllRefs(((FamilyInstance)elementByAllRefs).GetFarestConnector(connector.Origin).AllRefs, typeof(FamilyInstance));
								if (elementByAllRefs is Pipe && YJKRevitTools.isRiserPipe((Pipe)elementByAllRefs))
								{
									this.eles.Add(elementByAllRefs.Id);
								}
							}
						}
					}
				}
			}
		}

		private Element getElementByAllRefs(ConnectorSet allRefs, Type type)
		{
			Element result = null;
			if (allRefs != null)
			{
				ConnectorSetIterator connectorSetIterator = allRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector = obj as Connector;
					if (connector.Owner.GetType() != type)
					{
						result = connector.Owner;
					}
				}
			}
			return result;
		}

		private void hideSystemEle(List<Element> views)
		{
			foreach (Element element in views)
			{
				Autodesk.Revit.DB.View view = (Autodesk.Revit.DB.View)element;
				ViewDetailLevel viewDetailLevel = 0;
				if ((int)view.DetailLevel == 3)
				{
					view.DetailLevel = (ViewDetailLevel)2;
					this._doc.Regenerate();
                    viewDetailLevel = (ViewDetailLevel)3;
				}
				view.HideElements(this.eles);
				this._doc.Regenerate();
                if ((int)viewDetailLevel == 3)
				{
					view.DetailLevel = (ViewDetailLevel)3;
					this._doc.Regenerate();
				}
			}
		}

		private void setHideElement(ElementNode node)
		{
			if (node == null)
			{
				return;
			}
			this.eles.Add(node.Element.Id);
			if (node.SubElementNode != null && node.SubElementNode.Count > 0)
			{
				foreach (ElementNode hideElement in node.SubElementNode)
				{
					this.setHideElement(hideElement);
				}
			}
			if (node.Next != null)
			{
				this.setHideElement(node.Next);
			}
		}

		private List<ElementId> eles = new List<ElementId>();

		private UIDocument _uiDoc;

		private Document _doc;
	}
}
